#ifndef DATADEALER_HPP
#define DATADEALER_HPP
#include <QThread>
#include <QObject>
#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <tf2_msgs/TFMessage.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/point_types.h>
#include <pcl/io/ascii_io.h>
#include <pcl_conversions/pcl_conversions.h>
#include <boost/foreach.hpp>
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonValue>
#include <QCryptographicHash>
#include <QFile>
#include <QTextStream>
#include <QDir>


class PoseWorker : public QObject
{
    Q_OBJECT

public slots:
    void doWork(const QString&, const QString&, const QString&, const QString&);
signals:
    void readyResulat();
};


class ImageWorker : public QObject
{
    Q_OBJECT

public slots:
    void doWork(const QString&, const QString&, const QString&);
signals:
    void readyResult();
};


class PointCloudWorker : public QObject
{
    Q_OBJECT

public slots:
    void doWork(const QString&, const QString&, const QString&);
signals:
    void readyResult();
};

class PoseDataDealer : public QObject
{
    Q_OBJECT

public:
    QThread workerThread;
    PoseDataDealer();
    ~PoseDataDealer();
    void process(const QString&, const QString&, const QString&, const QString&);

signals:
    void operate(const QString&, const QString&, const QString&, const QString&);

};



class ImageDataDealer : public QObject
{
    Q_OBJECT

public:
    QThread workerThread;
    ImageDataDealer();
    ~ImageDataDealer();
    void process(const QString&, const QString&, const QString&);

signals:
    void operate(const QString&, const QString&, const QString&);
};


class PointCloudDataDealer : public QObject
{
    Q_OBJECT

public:
    QThread workerThread;
    PointCloudDataDealer();
    ~PointCloudDataDealer();
    void process(const QString&, const QString&, const QString&);

signals:
    void operate(const QString&, const QString&, const QString&);
};


//This the factory to get DataDealers
template <class T>
class DataDealerFactory
{
private:
    DataDealerFactory(){}
    ~DataDealerFactory(){}
    DataDealerFactory(const DataDealerFactory&);
    DataDealerFactory& operator =(const DataDealerFactory&);

public:
    static DataDealerFactory<T>* getInstance() { return new DataDealerFactory<T>; }
    T* createDataDealer() { return new T(); }
};



#endif // DATADEALER_HPP
